package com.googlecode.horncomb.orm.ibatis;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert;

import com.googlecode.horncomb.bean.filter.ConditionSet;
import com.googlecode.horncomb.bean.filter.SimpleMapConditionSet;
import com.googlecode.horncomb.bean.order.Order;
import com.googlecode.horncomb.bean.paged.CollectionWarpper;
import com.googlecode.horncomb.bean.paged.PagedList;

@SuppressWarnings("unchecked")
public class DefaultCommonSqlMapDao extends AbstractCommonSqlMapDao implements
		CommonSqlMapDao {

	protected String namespace;

	protected String buildStatementName(String simpleStmtName) {
		return this.buildStatementName(this.namespace, simpleStmtName);
	}

	public Object getById(Serializable id, Class entityType)
			throws DataAccessException {
		Assert.notNull(id);
		Assert.notNull(entityType);
		return this.doGet(new SimpleMapConditionSet().addConstraint(this
				.getIdName(entityType.getClass()), id), this.getStatementName,
				this.namespace);
	}

	protected Object doGet(ConditionSet cons) {
		return this.doGet(cons, this.getStatementName, this.namespace);
	}

	public void insert(Object entity) throws DataAccessException {
		this.insert(entity, this.insertStatementName, this.namespace);
	}

	public void update(Object entity) throws DataAccessException {
		this.doUpdate(null, entity, this.updateStatementName, this.namespace);
	}

	public void save(Object entity) throws DataAccessException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("save entity: " + entity);
		}
		if (this.isNew(entity)) {
			this.insert(entity);
		} else {
			this.update(entity);
		}
	}

	public PagedList queryByExample(Object example, Order order, int page,
			int pageSize) {
		return this.query(SqlMapEntityDaoUtil
				.convertExampleToConstraints(example), order, page, pageSize);
	}

	/**
	 * {@inheritDoc}
	 * @see com.googlecode.horncomb.orm.ibatis.SqlMapEntityDao#queryCountByExample(java.io.Serializable)
	 */
	public int queryCountByExample(Object example) {
		return this.queryCount(SqlMapEntityDaoUtil
				.convertExampleToConstraints(example));
	}

	/**
	 * {@inheritDoc}
	 */
	public Collection queryByExample(Object example) {
		return this.query(SqlMapEntityDaoUtil
				.convertExampleToConstraints(example));
	}

	/**
	 * {@inheritDoc}
	 * @see com.googlecode.horncomb.orm.ibatis.SqlMapEntityDao#queryByExample(java.io.Serializable,
	 *      java.util.Collection)
	 */
	public List queryByExample(Object example, Order order)
			throws DataAccessException {
		return this.query(SqlMapEntityDaoUtil
				.convertExampleToConstraints(example), order, this.namespace);
	}

	/**
	 * @param constraints
	 * @param order
	 * @return
	 * @throws DataAccessException
	 */
	protected Collection query(ConditionSet constraints)
			throws DataAccessException {
		return this.query(constraints, null, this.queryStatementName);
	}

	/**
	 * @param constraints
	 * @param order
	 * @return
	 * @throws DataAccessException
	 */
	protected List query(ConditionSet constraints, Order order)
			throws DataAccessException {
		return this.query(constraints, order, this.queryStatementName);
	}

	/**
	 * @param constraints
	 * @param order
	 * @param page
	 * @param pageSize
	 * @return
	 * @throws DataAccessException
	 */
	protected PagedList query(ConditionSet constraints, Order order, int page,
			int pageSize) throws DataAccessException {
		return this.query(constraints, order, page, pageSize,
				this.queryStatementName, this.queryCountStatementName);
	}

	/**
	 * 获得记录数
	 * @param constraints
	 * @return
	 */
	protected int queryCount(ConditionSet constraints) {
		return this.queryCount(constraints, this.queryCountStatementName,
				this.namespace);
	}

	// ----------------------------------------------------------------------
	// query function
	protected List query(ConditionSet constraints, Order order,
			String qryStmtName) throws DataAccessException {
		Assert.hasText(qryStmtName);
		CollectionWarpper<List<?>> r = this.doQuery(constraints, order, 0, 0,
				qryStmtName, null, this.namespace);
		return r.getSource();
	}

	protected PagedList query(ConditionSet constraints, Order order, int page,
			int pageSize, String qryStmtName, String queryCountStmtId)
			throws DataAccessException {
		Assert.hasText(qryStmtName);
		Assert.hasText(queryCountStmtId);
		Assert.isTrue(page > 0);
		Assert.isTrue(pageSize > 0);
		CollectionWarpper r = this.doQuery(constraints, order, page, pageSize,
				qryStmtName, queryCountStmtId, this.namespace);
		// always force result casted into PagedList
		return (PagedList) r;
	}

	/**
	 * @param defaultNamespace
	 *            the defaultNamespace to set
	 */
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}
}
